//	KUID.h : Kademia network GUID implementation
//
#include "kuid.h"

using namespace gKad;

KUID::KUID() {
	data[0] = 0;
	data[1] = 0;
	data[2] = 0;
	data[3] = 0;
}

KUID& KUID::SetValueRandomGUID()
{
	GUID guid;
	if (CoCreateGuid(&guid) != S_OK)
		return *this;
	data[0] = guid.Data1;
	data[1] = ((ULONG)guid.Data2) << 16 | guid.Data3;
	data[2] = ((ULONG)guid.Data4[0]) << 24 | ((ULONG)guid.Data4[1]) << 16 | ((ULONG)guid.Data4[2]) << 8 | ((ULONG)guid.Data4[3]);
	data[3] = ((ULONG)guid.Data4[4]) << 24 | ((ULONG)guid.Data4[5]) << 16 | ((ULONG)guid.Data4[6]) << 8 | ((ULONG)guid.Data4[7]);
	return *this;
}

//void KUID::ToBinaryString(CString *pstr, bool bTrim) const
//{
//	pstr->SetString(_T(""));
//	CString sElement;
//	int iBit;
//	for (int iIndex=0; iIndex<128; iIndex++)
//	{
//		iBit = GetBitNumber(iIndex);
//		if ((!bTrim) || (iBit != 0))
//		{
//			sElement.Format(_T("%d"), iBit);
//			pstr->Append(sElement);
//			bTrim = false;
//		}
//	}
//	if (pstr->GetLength() == 0)
//		pstr->SetString(_T("0"));
//}

int KUID::CompareTo(const KUID &uOther) const {
	for (int iIndex=0; iIndex<4; iIndex++) {
		if (data[iIndex] < uOther.data[iIndex])
			return -1;
		if (data[iIndex] > uOther.data[iIndex])
			return 1;
	}
	return 0;
}

int KUID::CompareTo(ULONG val) const {
	if ((data[0] > 0) || (data[1] > 0) || (data[2] > 0) || (data[3] > val))
		return 1;
	if (data[3] < val)
		return -1;
	return 0;
}

bool KUID::operator<  (const KUID &val) const {
	return (CompareTo(val) <  0);
}
bool KUID::operator>  (const KUID &val) const {
	return (CompareTo(val) >  0);
}
bool KUID::operator<= (const KUID &val) const {
	return (CompareTo(val) <= 0);
}
bool KUID::operator>= (const KUID &val) const {
	return (CompareTo(val) >= 0);
}
bool KUID::operator== (const KUID &val) const {
	return (CompareTo(val) == 0);
}
bool KUID::operator!= (const KUID &val) const {
	return (CompareTo(val) != 0);
}
KUID KUID::operator^ (const KUID &val) {
	KUID newGuid;

	newGuid.data[0] = data[0] ^ val.data[0];
	newGuid.data[1] = data[1] ^ val.data[1];
	newGuid.data[2] = data[2] ^ val.data[2];
	newGuid.data[3] = data[3] ^ val.data[3];

	return newGuid;
}

bool KUID::operator [] (UINT bit) {
	if (bit > 127)
		return false;

	// TODO optimize
	int base = bit / 32;
	int offset = 31 - (bit % 32);
	return ((data[base] >> offset) & 1);
}

void KUID::operator= (const KUID &val) const {
	// TODO implement
}